/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package mainclasses;

import ruter.map.AnonymousMapComponent;
import ruter.map.Map;
import ruter.simulator.Simulation;
import ruter.simulator.Updatable;
import ruter.simulator.Vehicle;

import java.awt.Color;
import java.io.File;
import java.io.IOException;
import java.util.Random;

import jxl.write.WriteException;
import components.ExcelWriter;
import components.RobotPilot;
import ruter.network.AdhocNetwork;

/**
 *
 * @author camilo
 */
public class ConnectivityReporter implements Updatable {

	public static final int[] MAP_DIMENSION = {5000, 5000};
	public static final int NODE_RADIUS = 90;
	public static final int NUMBER_OF_ROBOTS = 15;
	public static final long FRAME_TIME = Simulation.ACCURACY_HIGH;
	public static final int MAX_PPM = 10;
	public static final int MIN_PPM = 1;

	private Map map;
	private AdhocNetwork network;
	private Simulation simulation;
	private boolean findOrNot, allFind;
	private int robotsFound, numberGroups;

	private ExcelWriter writer;

	public static void main(String args[]) {
		ConnectivityReporter test = new ConnectivityReporter();
	}

	public ConnectivityReporter() {

		// Excel
		try {
			writer = new ExcelWriter(new File("/Users/Camilo/Desktop/simulation/Connectivity.xls"));
		} catch (IOException e) {
			System.out.println("IOException");
		}

		// Map
		map = new Map(MAP_DIMENSION[0], MAP_DIMENSION[1], Double.MAX_VALUE);

		// First simulation
		restartSimulation();
	}

	public void restartSimulation() {

		// Restarting flags
		findOrNot = false;
		allFind = false;

		// Network
		network = new AdhocNetwork(NODE_RADIUS);

		// Simulation
		simulation = new Simulation(null, map, network, FRAME_TIME);
		simulation.setMaximumSimulationSpeed();
		simulation.addUpdatableElementToThread(this);

		// Adding new robots
		addRobots();

		// Start simulation
		simulation.start();
	}

	private void addRobots() {
		Random random = new Random();
		AnonymousMapComponent target = new AnonymousMapComponent(map.getXBounds()*0.1, map.getYBounds()*0.1);
		int mod = (int) Math.ceil(Math.sqrt(NUMBER_OF_ROBOTS));
		int refX = (int) (map.getXBounds()/2 - mod*3);
		int refY = (int) (map.getYBounds()/2 - mod*3);
		for (int i = 0; i < NUMBER_OF_ROBOTS; i++) {
			int x = i % mod;
			int y = (int) (i/(double)mod);
			Vehicle v = new Vehicle(refX + x*mod, refY + y*mod, 2, 1, 1, 180);
			RobotPilot pilot = new RobotPilot(map, target, FRAME_TIME/1000d,simulation);
			pilot.setUseRules(true);
			v.putDriver(pilot);
			v.putMap(map);
			network.addNode(pilot);
			simulation.addVehicle(v, new Color(random.nextInt()));
		}
	}

	@Override
	public void update(Simulation simulation) {
		int robotsFoundTarget = 0;
		for (int i = 0; i < simulation.getVehicles().size(); i++) {
			RobotPilot robot = (RobotPilot) simulation.getVehicles().get(i).getDriver();
			if(robot.getTimeToFind()!=0){
				if(!findOrNot) {
					System.out.print(""+(robot.getTimeToFind()/1000d));
					findOrNot = true;
				}
				robotsFoundTarget ++;
			}
		}
		int numGroups = network.numberOfSubnets();

		// Saving if a change was made
		if(numberGroups != numGroups || robotsFound != robotsFoundTarget) {
			numberGroups = numGroups;
			try {
				writer.setColumn(0);
				writer.writeNumber(simulation.getRealTime());
				writer.setColumn(1);
				writer.writeNumber(network.numberOfSubnets());
				writer.setColumn(2);
				writer.writeNumber(robotsFoundTarget);
				writer.enter();
			} catch (WriteException e) {
				System.out.println("WriteException");
			}
		}

		// Printing for control purpose
		if(robotsFound != robotsFoundTarget) {
			robotsFound = robotsFoundTarget;
			System.out.println("Robots found target: "+robotsFoundTarget);
		}

		// Finishing when all robots find the target
		if(robotsFoundTarget == NUMBER_OF_ROBOTS) {
			try {
				writer.saveDocument();
				writer.closeDocument();
			} catch (WriteException | IOException e) {
				System.out.println("Impossible to save");
			}
			System.exit(0);
		}
	}

	@Override
	public void update(double x, double y) {
	}
}
